<?php
header("Content-type: text/html; charset=utf-8"); 
define('ROOT',dirname(__FILE__).'/');
require_once ROOT.'common.inc.php';
$uptype!='bakupds'&&!in_array('0',$larr)&&adminmsg('你没有被赋予操作该项的权限！');
$uptype=='bakupds'&&!in_array('1',$larr)&&adminmsg('你没有被赋予操作该项的权限！');
$query = $db->query("SELECT value FROM {$tablepre}config WHERE variable='backupdir'");
if(!$backupdir=$db->result($query,0))
{
	$backupdir = rand(123456,789456);
	@mkdir(ROOT."data/backup_$backupdir",0777);
	$db->query("REPLACE INTO {$tablepre}config(variable,value) VALUE ('backupdir','$backupdir')");
}
$backupdir = 'backup_'.$backupdir;
if(!is_dir(ROOT."data/$backupdir"))
{
	mkdir(ROOT.'/data/'.$backupdir,0777);
}
if($uptype =='bakupds')
{
	
	$frament = '&uptype=bakupds';
}
if($action=='export')
{
	if($uptype=='bakupds') 
	if(!submitcheck('exportsubmit',1))
	{
		$shelldisabled = function_exists('shell_exec') ? '' : 'disabled';
		$sqlcharset = "<input type=\"radio\" name=\"sqlcharset\" value=\"\" checked>默认"
		.($dbcharset ? " &nbsp;<input type=\"radio\" name=\"sqlcharset\" value=\"$dbcharset\">".strtolower($dbcharset) : '').
		($db->version()>'4.1'&&$dbcharset != 'utf-8' ? " &nbsp; <input class=\"radio\" type=\"radio\" name=\"sqlcharset\" value='utf8'> UTF-8</option>" : '');
		$tables = array();
		if($uptype=='bakupds') $tablepre = NULL;
		$tables = fetchtablelist($tablepre);
		$rowcount = 0;
		$tablelist = '';
		foreach ($tables as $table)
		{
			$tablelist .= ($rowcount%4 ? '' : '</tr><tr>')."<td><input type=\"checkbox\" name=\"customtables[]\" value=\"$table[Name]\" checked>$table[Name]</td>\n\n";
			$rowcount++;
		}
		$includefile=ROOT.'templates/msystem/date.html';
		include $includefile;
	}
	else
	{
		$tables = array();
		$db->query("SET SQL_QUOTE_SHOW_CREATE=0",'SILENT');
		if($type=='custom')
		{
			$customq = $db->query("SELECT value FROM {$tablepre}settings WHERE variable='custombakup'");
			$result = $db->fetch_array($customq);
			if(!empty($customtables))
			{
				$tmpvar = empty($customtables) ? serialize(array()) :addslashes(serialize($customtables));
				$db->query("REPLACE INTO {$tablepre}settings (variable,value) VALUES ('custombakup','$tmpvar')");
			}
			$customtables = !empty($result['value']) ? unserialize($result['value']):$customtables ;
			$tables = &$customtables;
		}
		else
		{
			$tables = arraykeys2(fetchtablelist($tablepre),'Name');
		}
		if(!is_array($tables)|| empty($tables))
		{
			adminmsg('database_export_custom_invalid',"database.inc.php?action=export$frament");
		}
		$volume = intval($volume) + 1;
		$idstring = '# Indentify: '.base64_encode("$timestamp,$version,$baktype,$type,$method,$volume")."@\n";
		$dumpcharset = $sqlcharset ? $sqlcharset : str_replace('-','',$GLOBALS['charset']);
		$setnames = ($sqlcharset && $db->version()>'4.1' && ($sqlcompat || $sqlcompat=='MYSQL41')) ? "SET NAMES '$dumpcharset'" : '';
		if ($db->version()>'4.1')
		{
			if($sqlcharset)
			{
				$db->query("SET NAMES '$sqlcharset'");
			}
			if ($sqlcompat=='MYSQL40')
			{
				$db->query("SET SQL_MODE='MYSQL40'");
			}
			elseif ($sqlcompat=='MYSQL41')
			{
				$db->query("SET SQL_MODE=''");
			}
		}
		$backupfilename = ROOT.'data/'.$backupdir.'/'.date('md').'-'.str_replace(array('/','\\','.'),'',$filename);
		if($method=='multivol')
		{
			$sqldump = '';
			$tableid = intval($tableid);
			$startfrom = intval($startfrom);
			$complete = TRUE;
			for (;$complete&&$tableid<count($tables)&&strlen($sqldump)+500 < $sizelimit*1000;$tableid++)
			{
				$sqldump .= sqldumptable($tables[$tableid], $startfrom, strlen($sqldump));
				if($complete)
				{
					$startfrom = 0;
				}
			}
			$dumpfile = $backupfilename."-%s".'.sql';
			if($uptype=='bakupds') $dumpfile = $backupfilename."-ds-%s".'.sql';
			!$complete && $tableid--;
			if(trim($sqldump))
			{
				$sqldump = "$idstring".
				"# <?exit();?>\n".
				"# Multi-Volume Data Dump Vol.$volume\n".
				"# Version: hh $version\n".
				"# Time: $systime\n".
				"# Type: $type\n".
				"# Table Prefix: $tablepre\n".
				"#\n".
				"# Home: http://www.b028.com\n".
				"# Please visit our website for newest infomation about hh\n".
				"# --------------------------------------------------------\n\n\n".
				"$setnames".
				$sqldump;
				$dumpfilename = sprintf($dumpfile,$volume);
				@$fp = fopen($dumpfilename,'wb');
				@flock($fp,2);
				if(!@fwrite($fp,$sqldump))
				{
					@fclose($fp);
					adminmsg('database_export_file_invalid',"database.inc.php?action=export$frament");
				}
				else
				{
					fclose($fp);
					adminmsg('database_export_multivol_redirect',"database.inc.php?action=export&baktype=".rawurlencode($baktype)."&type=".rawurlencode($type)."&filename=".rawurlencode($filename)."&method=multivol&sizelimit=".rawurlencode($sizelimit)."&volume=".rawurlencode($volume)."&tableid=".rawurlencode($tableid)."&startfrom=".rawurlencode($startrow)."&extendins=".rawurlencode($extendins)."&sqlcharset=".rawurlencode($sqlcharset)."&sqlcompat=".rawurlencode($sqlcompat)."&exportsubmit=yes&usehex=$usehex{$frament}");
				}
			}
			else
			{
				$volume--;
				$filelist = '<ul>';
				@touch(ROOT.'data/'.$backupdir.'/index.html');
				for($i=1;$i<=$volume;$i++)
				{
					$filename = sprintf($dumpfile,$i);
					$filelist .=  "<li><a href=\"$filename\">$filename\n";
				}
				$filelist='';
				adminmsg('database_export_multivol_succeed',"database.inc.php?action=export&uptype=bakupds");
			
			}
		}
	}
}
elseif ($action=='import')
{
	if(!submitcheck('importsubmit',1) && !submitcheck('deletesubmit',1))
	{
		$exportlog = array ();
		if(is_dir(ROOT.'data/'.$backupdir))
		{
			$dir = dir(ROOT.'data/'.$backupdir);
			while($entry = $dir->read())
			{
				$entry = ROOT.'data/'.$backupdir.'/'.$entry;
				if(is_file($entry))
				{
					if(preg_match("/\.sql$/i",$entry))
					{
						if($uptype=='bakupds'&&!strstr($entry,'-ds-'))
						{
							continue;
						}elseif ($uptype!='bakupds'&&strstr($entry,'-ds-'))
						{
							continue;
						}
						$filesize = filesize($entry);
						$fp = fopen($entry,'rb');
						$identify = explode(',',base64_decode(preg_replace("/^# Indentify: ([a-zA-Z0-9=]+)@.*/s","\\1",fgets($fp,250))));
						fclose($fp);
						$exportlog[] = array(
						'version' => $identify[1],
						'type' => $identify[3],
						'method' => $identify[4],
						'volume' => $identify[5],
						'filename' => $entry,
						'dateline' => filemtime($entry),
						'size' => $filesize
						);
					}
				}
			}
			$dir->close();
			$exportinfo = '';
			foreach($exportlog as $info) {
			$info['dateline'] = is_int($info['dateline']) ? gmdate("Y-m-d H:i:s", $info['dateline']) : $lang['unknown'];
			$info['size'] = sizecount($info['size']);
			$info['volume'] = $info['method'] == 'multivol' ? $info['volume'] : '';
			$info['method'] = $info['type'] != 'zip' ? ($info['method'] == 'multivol' ? '分卷': $lang['database_shell']) : '';
			$exportinfo .= "<tr align=\"center\"><td class=\"altbg1\"><input class=\"checkbox\" type=\"checkbox\" name=\"delete[]\" value=\"".basename($info['filename'])."\"></td>\n".
				"<td class=\"altbg2\">".substr(strrchr($info['filename'], "/"), 1)."</td>\n".
				"<td class=\"altbg1\">$info[version]</td>\n".
				"<td class=\"altbg2\">$info[dateline]</td>\n".
				"<td class=\"altbg1\">$info[type]</td>\n".
				"<td class=\"altbg2\">$info[size]</td>\n".
				"<td class=\"altbg1\">$info[method]</td>\n".
				"<td class=\"altbg2\">$info[volume]</td>\n".
				"<td class=\"altbg1\"><a href=\"database.inc.php?action=import&from=server&datafile_server=$info[filename]&importsubmit=yes$frament\"".
				" onclick=\"return confirm('确认导入！');\"".">[导入]</a></td>\n";
		}
		}
		else
		{
			adminmsg('database_export_dest_invalid',"database.inc.php?action=import$frament");
		}
		include systemplate('date_hf');
	}
	elseif (submitcheck('importsubmit',1))
	{
		$readerror = 0;
		if($from == 'server') {
			$datafile = $datafile_server;
		}
		if(@$fp = fopen($datafile, 'rb')) {
			$sqldump = fgets($fp, 256);
			$identify = explode(',', base64_decode(preg_replace("/^# Indentify:\s*([a-zA-Z0-9=]+)@.*/s", "\\1", $sqldump)));
			$dumpinfo = array('method' => $identify[4], 'volume' => intval($identify[5]));
			if($dumpinfo['method'] == 'multivol') {
				$sqldump .= fread($fp, filesize($datafile));
			}
			fclose($fp);
		}else {
			if($autoimport) {
				adminmsg('database_import_multivol_succeed',"database.inc.php?action=import$frament");
			} else {
				adminmsg('database_import_file_illegal',"database.inc.php?action=import$frament");
			}
		}
		if($dumpinfo['method'] == 'multivol')
		{
			$sqlquery = sqlsplit($sqldump);
			foreach ($sqlquery as $sql)
			{
				$sql = trim($sql);
				if(!empty($sql))
				{
					$db->query($sql, 'SILENT');
					if(($sqlerror = $db->error()) && $db->errno() != 1062) {
						$db->halt('MySQL Query Error', $sql);
					}
				}
			}
			@unlink($datafile);
			$datafile_next = preg_replace("/-($dumpinfo[volume])(\..+)$/", "-".($dumpinfo['volume'] + 1)."\\2", $datafile_server);
			if($dumpinfo['volume'] == 1) {
				adminmsg('database_import_multivol_prompt',
				"database.inc.php?action=import&from=server&datafile_server=$datafile_next&autoimport=yes&importsubmit=yes$frament");
			} elseif($autoimport) {
				adminmsg('database_import_multivol_redirect', "database.inc.php?action=import&from=server&datafile_server=$datafile_next&autoimport=yes&importsubmit=yes$frament");
			}
		}
	}elseif(submitcheck('deletesubmit',1)) {
		if(is_array($delete)) {
			foreach($delete as $filename) {
				@unlink('./data/'.$backupdir.'/'.str_replace(array('/', '\\'), '', $filename));
			}
			adminmsg('database_file_delete_succeed',"database.inc.php?action=import$frament");
		} else {
			adminmsg('database_file_delete_invalid',"database.inc.php?action=import$frament");
		}
	}
}
elseif ($action=='optimize')
{
$optimizetable = '';
$totalsize = 0;
$tablearray =  array( 0 =>$tablepre);
if($uptype == 'bakupds')
{
	
	$tablearray = array(0=>'');
}
if(!submitcheck('optimizesubmit',1)) {
	$totalsize=0;
	foreach($tablearray as $tp) {
		if($uptype=='bakupds') 
		{
			
			$sql = "SHOW TABLE STATUS";
		}else {
			$sql = "SHOW TABLE STATUS LIKE '$tp%'";
		}
		$query = $db->query($sql, 'SILENT');
		
		while($table = $db->fetch_array($query)) {
			//print_r($table);
			if(!$table['Data_free']) continue;
			if( $table['Engine'] == 'MyISAM') {
				$checked = $table['Engine'] == 'MyISAM' ? 'checked' : 'disabled';
				$optimelist.="<tr><td class=\"altbg1\" align=\"center\"><input class=\"checkbox\" type=\"checkbox\" name=\"optimizetables[]\" value=\"$table[Name]\" $checked></td>\n".
				"<td class=\"altbg2\" align=\"center\">$table[Name]</td>\n".
				"<td class=\"altbg1\" align=\"center\">".$table['Engine']."</td>\n".
				"<td class=\"altbg2\" align=\"center\">$table[Rows]</td>\n".
				"<td class=\"altbg1\" align=\"center\">$table[Data_length]</td>\n".
				"<td class=\"altbg2\" align=\"center\">$table[Index_length]</td>\n".
				"<td class=\"altbg1\" align=\"center\">$table[Data_free]</td></tr>\n";
				$totalsize += $table['Data_length'] + $table['Index_length'];
			}
		}
		//echo "aaaaaaaaaa=<br>\n".$totalsize;
	}
	//die($totalsize);
	if(empty($totalsize)) {
		adminmsg('database_optimize_done',"database.inc.php?action=optimize$frament");
	} else {
		$optimelist.="<tr><td colspan=\"7\" align=\"right\">数据总大小： ".sizecount($totalsize)."</td></tr>";
	}
} else {
	//$db->query("DELETE FROM {$tablepre}subscriptions", 'UNBUFFERED');
	//$db->query("UPDATE {$tablepre}memberfields SET authstr=''", 'UNBUFFERED');
	foreach($tablearray as $tp) {
		$query = $db->query("SHOW TABLE STATUS LIKE '$tp%'", 'SILENT');
		while($table = $db->fetch_array($query)) {
			//print_r($table);
			if(is_array($optimizetables) && in_array($table['Name'], $optimizetables)) {
				$db->query("OPTIMIZE TABLE $table[Name]");
			}
			$optimelist.= "<tr>\n".
			"<td class=\"altbg1\" align=\"center\">".$lang['yes']."</td>\n".
			"<td class=\"altbg2\" align=\"center\">$table[Name]</td>\n".
			"<td class=\"altbg1\" align=\"center\">".($db->version() > '4.1' ?  $table['Engine'] : $table['Type'])."</td>\n".
			"<td class=\"altbg2\" align=\"center\">$table[Rows]</td>\n".
			"<td class=\"altbg1\" align=\"center\">$table[Data_length]</td>\n".
			"<td class=\"altbg2\" align=\"center\">$table[Index_length]</td>\n".
			"<td class=\"altbg1\" align=\"center\">0</td>\n".
			"</tr>\n";
			$totalsize += $table['Data_length'] + $table['Index_length'];
		}
		//die();
	}
	$optimelist.="<tr><td colspan=\"7\" align=\"right\">数据总大小：".sizecount($totalsize)."</td></tr>";
}
   !empty($totalsize)&&include systemplate('date_yh');
}
elseif ($action=='runquery')
{
	if(!submitcheck('sqlsubmit',1))
	{
		include systemplate('date_sj');
		exit();
	}
	$sqlquery = sqlsplit(str_replace(array(' cdb_', ' {tablepre}', ' `cdb_'), array(' '.$tablepre, ' '.$tablepre, ' `'.$tablepre), $queries));
	$affected_rows = 0;
	foreach($sqlquery as $sql) {
		if(trim($sql) != '') {
			$db->query(stripslashes($sql), 'SILENT');
			if($sqlerror = $db->error()) {
				break;
			} else {
				$affected_rows += intval($db->affected_rows());
			}
		}
	}
	adminmsg($sqlerror ? 'database_run_query_invalid' : 'database_run_query_succeed',"database.inc.php?action=runquery$frament");
}
function fetchtablelist($tablepre = '')
{
	global $db,$uptype;
	$uptype=='bakupds' && $tablepre = '';
	$arr = explode('.',$tablepre);
	$dbname = $arr[1] ? $arr[0] : '';
	$sqladd = $dbname ? "FROM $dbname LIKE '$arr[1]%'" : "LIKE '$tablepre%'";
	!$tablepre && $tablepre='*';
	$tables = $table = array();
	$query = $db->query("SHOW TABLE STATUS $sqladd");
	while ($table=$db->fetch_array($query))
	{
		$table['Name'] = ($dbname ? "$dbname." : '').$table['Name'];
		$tables[] = $table;
	}
	return  $tables;
}
function arraykeys2($array,$key2)
{
	$return = array();
	foreach ($array as $val)
	{
		$return[] = $val[$key2];
	}
	return $return;
}
function sqlsplit($sql)
{
	$sql = str_replace("\r","\n",$sql);
	$ret = array();
	$num = 0;
	$queriesarray = explode(";\n",$sql);
	foreach ($queriesarray as $query)
	{
		$queries = explode("\n",$query);
		foreach ($queries as $query)
		{
			$ret[$num] .= $query{0}=='#' ? NULL : $query;
		}
		$num++;
	}
	return $ret;
}

function sizecount($filesize) {
	if($filesize >= 1073741824) {
		$filesize = round($filesize / 1073741824 * 100) / 100 . ' GB';
	} elseif($filesize >= 1048576) {
		$filesize = round($filesize / 1048576 * 100) / 100 . ' MB';
	} elseif($filesize >= 1024) {
		$filesize = round($filesize / 1024 * 100) / 100 . ' KB';
	} else {
		$filesize = $filesize . ' Bytes';
	}
	return $filesize;
}
?>
